import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Reader;
import java.util.HashSet;
import java.util.Set;

import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.index.CorruptIndexException;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.queryParser.ParseException;
import org.apache.lucene.queryParser.QueryParser;
import org.apache.lucene.search.Hits;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;
import org.apache.lucene.store.LockObtainFailedException;

/**
 * 
 * @author Stavros Nicolakopoulos
 * @since 16 Ιουν 2013
 * 
 */

public class CommonWordsFinder {
	
	public static final String INDEX_DIRECTORY = "indexDirectory";

	public static void main(String[] args) throws Exception {
		
		String usage = "CommonWordsFinder\n\n"
				         + " [-input1 INPUT FILE] [-input2 INPUT FILE] [-output OUTPUT FILE]";
		
		String inputFilePath1 = null;
		String inputFilePath2 = null;
		String outputFilePath = null;
		
		for (int i = 0; i < args.length; i++) {
			if ("-input1".equals(args[i])) {
				inputFilePath1 = args[i + 1];
				i++;
			} else if ("-input2".equals(args[i])) {
				inputFilePath2 = args[i + 1];
				i++;
			} else if ("-output".equals(args[i])) {
				outputFilePath = args[i + 1];
			}
		}
		
		if(inputFilePath1 == null || inputFilePath2 == null || outputFilePath == null) {
			System.err.println("Usage: " + usage);
			System.exit(1);
		}
			

		File inputfile1 = new File(inputFilePath1);
		File inputfile2 = new File(inputFilePath2);
		File outputFile = new File(outputFilePath);

		File[] inputFiles = { inputfile1, inputfile2 };
		
		CommonWordsFinder finder = new CommonWordsFinder();
		finder.createIndex(inputFiles);
		finder.findWords(inputFiles, outputFile);

	}

	public void createIndex(File[] files) throws CorruptIndexException, LockObtainFailedException, IOException {
		Analyzer analyzer = new StandardAnalyzer();
		IndexWriter indexWriter = new IndexWriter(INDEX_DIRECTORY, analyzer, true);
		for (File file : files) {
			Document document = new Document();

			String path = file.getCanonicalPath();
			document.add(new Field("path", path, Field.Store.YES, Field.Index.UN_TOKENIZED));

			Reader reader = new FileReader(file);
			document.add(new Field("contents", reader));

			indexWriter.addDocument(document);
		}
		indexWriter.optimize();
		indexWriter.close();
	}
	
	public void findWords(File[] inputFiles, File outputFile) throws Exception {
		Set<String> wordsInCommon = new HashSet<>();
		
		for(File file : inputFiles) {
			BufferedReader br = new BufferedReader(new FileReader(file));
			String line;
			String word;
			while ((line = br.readLine()) != null) {
			   word = line.trim();
			   if(wordIsCommon(word))
				   wordsInCommon.add(word);
			}
			br.close();
		}
		
		StringBuilder buffer = new StringBuilder();
		for(String word : wordsInCommon) {
			buffer.append(word + "\n");
		}
		
		BufferedWriter bw = new BufferedWriter(new FileWriter(outputFile));
		bw.write(buffer.toString());
		bw.close();
		
	}
	
	
	public boolean wordIsCommon(String word) throws IOException, ParseException {
		Directory directory = FSDirectory.getDirectory(INDEX_DIRECTORY);
		IndexReader indexReader = IndexReader.open(directory);
		IndexSearcher indexSearcher = new IndexSearcher(indexReader);

		Analyzer analyzer = new StandardAnalyzer();
		QueryParser queryParser = new QueryParser("contents", analyzer);
		Query query = queryParser.parse(word);
		Hits hits = indexSearcher.search(query);
		return hits.length() == 2;
	}

}
